﻿#region License
// (c) Intergen.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using MediaWiki.Office.Model.Utilities;

namespace MediaWiki.Office.Model
{
  public class Border : IEquatable<Border>
  {
    private ContentProperties _parentProperties;
    private DocumentColor? _color;
    private Unit? _spacing;
    private Unit? _borderWidth;
    private string _themeColor;
    private string _borderStyle;
    private Func<Func<Border, object>, object> _valueGetter;

    public Func<Func<Border, object>, object> ValueGetter
    {
      // if no value getter has been defined, get the value off the current object
      get { return _valueGetter ?? (g => g(this)); }
    }

    public bool IsDefined
    {
      get { return !string.IsNullOrEmpty(BorderStyle); }
    }

    public string BorderStyle
    {
      get { return (string)ValueGetter(b => b._borderStyle); }
      set { _borderStyle = value; }
    }

    public string ThemeColor
    {
      get { return (string)ValueGetter(b => b._themeColor); }
      set { _themeColor = value; }
    }

    public Unit? BorderWidth
    {
      get { return (Unit?)ValueGetter(b => b._borderWidth); }
      set { _borderWidth = value; }
    }

    public Unit? Spacing
    {
      get { return (Unit?)ValueGetter(b => b._spacing); }
      set { _spacing = value; }
    }

    public DocumentColor? Color
    {
      get { return (DocumentColor?)ValueGetter(b => b._color); }
      set { _color = value; }
    }

    private Border(ContentProperties parentProperties, XElement borderElement)
      : this(parentProperties, borderElement, null)
    {
    }

    private Border(ContentProperties parentProperties, XElement borderElement, Func<Func<Border, object>, object> valueGetter)
    {
      _parentProperties = parentProperties;
      _valueGetter = valueGetter;

      if (borderElement == null)
        return;

      XNamespace ns = borderElement.Name.Namespace;

      _borderStyle = (string)borderElement.Attribute(ns + "val");
      _themeColor = (string)borderElement.Attribute(ns + "themeColor");
      _borderWidth = Unit.EighthOfAPoint((int?)borderElement.Attribute(ns + "sz"));
      _spacing = Unit.Point((int?)borderElement.Attribute(ns + "space"));
      _color = DocumentColor.Parse((string)borderElement.Attribute(ns + "color"));
    }

    public static Border Create(ContentProperties parentProperties, XElement borderElement, Func<Func<Border, object>, object> valueGetter)
    {
      return new Border(parentProperties, borderElement, valueGetter);
    }

    public bool Equals(Border other)
    {
      if (other == null)
        return false;

      if (BorderStyle != other.BorderStyle)
        return false;

      if (!Nullable.Equals(BorderWidth, other.BorderWidth))
        return false;

      if (!Nullable.Equals(Color, other.Color))
        return false;

      if (!Nullable.Equals(Spacing, other.Spacing))
        return false;

      if (ThemeColor != other.ThemeColor)
        return false;

      return true;
    }

    public static bool Equals(Border b1, Border b2)
    {
      if (b1 != null)
        return b1.Equals(b2);
      else
        return (b2 == null);
    }
  }
}